home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / compress / gnucpio.zip / MT.C < prev    next >
C/C++ Source or Header  |  1995-11-22  |  7KB  |  325 lines

  1. /* mt -- control magnetic tape drive operation
  2.    Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  17.    */
  18.  
  19.  
  20. /* If -f is not given, the environment variable TAPE is used;
  21.    if that is not set, a default device defined in sys/mtio.h is used.
  22.    The device must be either a character special file or a remote
  23.    tape drive with the form "[user@]system:path".
  24.    The default count is 1.  Some operations ignore it.
  25.  
  26.    Exit status:
  27.    0    success
  28.    1    invalid operation or device name
  29.    2    operation failed
  30.  
  31.    Operations (unique abbreviations are accepted):
  32.    eof, weof    Write COUNT EOF marks at current position on tape.
  33.    fsf        Forward space COUNT files.
  34.         Tape is positioned on the first block of the file.
  35.    bsf        Backward space COUNT files.
  36.         Tape is positioned on the first block of the file.
  37.    fsr        Forward space COUNT records.
  38.    bsr        Backward space COUNT records.
  39.    bsfm        Backward space COUNT file marks.
  40.         Tape is positioned on the beginning-of-the-tape side of
  41.         the file mark.
  42.    asf        Absolute space to file number COUNT.
  43.         Equivalent to rewind followed by fsf COUNT.
  44.    eom        Space to the end of the recorded media on the tape
  45.         (for appending files onto tapes).
  46.    rewind    Rewind the tape.
  47.    offline, rewoffl
  48.         Rewind the tape and, if applicable, unload the tape.
  49.    status    Print status information about the tape unit.
  50.    retension    Rewind the tape, then wind it to the end of the reel,
  51.         then rewind it again.
  52.    erase    Erase the tape.
  53.  
  54.    David MacKenzie <djm@gnu.ai.mit.edu> */
  55.  
  56. #include <stdio.h>
  57. #include <sys/types.h>
  58. #include <sys/stat.h>
  59. #include <sys/ioctl.h>
  60. #ifdef HAVE_SYS_MTIO_H
  61. #ifdef HAVE_SYS_IO_TRIOCTL_H
  62. #include <sys/io/trioctl.h>
  63. #endif
  64. #include <sys/mtio.h>
  65. #endif
  66. #include <sys/file.h>
  67. #include <fcntl.h>
  68. #include <errno.h>
  69. #include <getopt.h>
  70.  
  71. #if defined(HAVE_UNISTD_H)
  72. #include <unistd.h>
  73. #endif
  74. #include "rmt.h"
  75.  
  76. #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
  77. #include <string.h>
  78. #else
  79. #include <strings.h>
  80. #endif
  81.  
  82. #if defined(STDC_HEADERS)
  83. #include <stdlib.h>
  84. #else
  85. extern int errno;
  86. char *getenv ();
  87. int atoi ();
  88. void exit ();
  89. #endif
  90.  
  91. int fstat ();
  92.  
  93. int argmatch ();
  94. void check_type ();
  95. void error ();
  96. void invalid_arg ();
  97. void perform_operation ();
  98. void print_status ();
  99. void usage ();
  100.  
  101. char *opnames[] =
  102. {
  103.   "eof", "weof", "fsf", "bsf", "fsr", "bsr",
  104.   "rewind", "offline", "rewoffl", "eject", "status",
  105. #ifdef MTBSFM
  106.   "bsfm",
  107. #endif
  108. #ifdef MTEOM
  109.   "eom",
  110. #endif
  111. #ifdef MTRETEN
  112.   "retension",
  113. #endif
  114. #ifdef MTERASE
  115.   "erase",
  116. #endif
  117.   "asf",
  118. #ifdef MTFSFM
  119.   "fsfm",
  120. #endif
  121. #ifdef MTSEEK
  122.   "seek",
  123. #endif
  124.   NULL
  125. };
  126.  
  127. #define MTASF 600        /* Random unused number.  */
  128. short operations[] =
  129. {
  130.   MTWEOF, MTWEOF, MTFSF, MTBSF, MTFSR, MTBSR,
  131.   MTREW, MTOFFL, MTOFFL, MTOFFL, MTNOP,
  132. #ifdef MTBSFM
  133.   MTBSFM,
  134. #endif
  135. #ifdef MTEOM
  136.   MTEOM,
  137. #endif
  138. #ifdef MTRETEN
  139.   MTRETEN,
  140. #endif
  141. #ifdef MTERASE
  142.   MTERASE,
  143. #endif
  144.   MTASF,
  145. #ifdef MTFSFM
  146.   MTFSFM,
  147. #endif
  148. #ifdef MTSEEK
  149.   MTSEEK,
  150. #endif
  151.   0
  152. };
  153.  
  154. /* If nonzero, don't consider file names that contain a `:' to be
  155.    on remote hosts; all files are local.  Always zero for mt;
  156.    since when do local device names contain colons?  */
  157. int f_force_local = 0;
  158.  
  159. struct option longopts[] =
  160. {
  161.   {"file", 1, NULL, 'f'},
  162.   {"version", 0, NULL, 'V'},
  163.   {"help", 0, NULL, 'H'},
  164.   {NULL, 0, NULL, 0}
  165. };
  166.  
  167. /* The name this program was run with.  */
  168. char *program_name;
  169.  
  170. void
  171. main (argc, argv)
  172.      int argc;
  173.      char **argv;
  174. {
  175.   extern char *version_string;
  176.   short operation;
  177.   int count;
  178.   char *tapedev;
  179.   int tapedesc;
  180.   int i;
  181.  
  182.   program_name = argv[0];
  183.   tapedev = NULL;
  184.   count = 1;
  185.  
  186.   while ((i = getopt_long (argc, argv, "f:t:V:H", longopts, (int *) 0)) != -1)
  187.     {
  188.       switch (i)
  189.     {
  190.     case 'f':
  191.     case 't':
  192.       tapedev = optarg;
  193.       break;
  194.  
  195.     case 'V':
  196.       printf ("GNU mt %s", version_string);
  197.       exit (0);
  198.       break;
  199.  
  200.     case 'H':
  201.     default:
  202.       usage (stdout, 0);
  203.     }
  204.     }
  205.  
  206.   if (optind == argc)
  207.     usage (stderr, 1);
  208.  
  209.   i = argmatch (argv[optind], opnames);
  210.   if (i < 0)
  211.     {
  212.       invalid_arg ("tape operation", argv[optind], i);
  213.       exit (1);
  214.     }
  215.   operation = operations[i];
  216.  
  217.   if (++optind < argc)
  218.     count = atoi (argv[optind]);
  219.   if (++optind < argc)
  220.     usage (stderr, 1);
  221.  
  222.   if (tapedev == NULL)
  223.     {
  224.       tapedev = getenv ("TAPE");
  225.       if (tapedev == NULL)
  226. #ifdef DEFTAPE            /* From sys/mtio.h.  */
  227.         tapedev = DEFTAPE;
  228. #else
  229.     error (1, 0, "no tape device specified");
  230. #endif
  231.     }
  232.  
  233.   if ( (operation == MTWEOF)
  234. #ifdef MTERASE
  235.        || (operation == MTERASE)
  236. #endif
  237.     )
  238.     tapedesc = rmtopen (tapedev, O_WRONLY, 0);
  239.   else
  240.     tapedesc = rmtopen (tapedev, O_RDONLY, 0);
  241.   if (tapedesc == -1)
  242.     error (1, errno, "%s", tapedev);
  243.   check_type (tapedev, tapedesc);
  244.  
  245.   if (operation == MTASF)
  246.     {
  247.       perform_operation (tapedev, tapedesc, MTREW, 1);
  248.       operation = MTFSF;
  249.     }
  250.   perform_operation (tapedev, tapedesc, operation, count);
  251.   if (operation == MTNOP)
  252.     print_status (tapedev, tapedesc);
  253.  
  254.   if (rmtclose (tapedesc) == -1)
  255.     error (2, errno, "%s", tapedev);
  256.  
  257.   exit (0);
  258. }
  259.  
  260. void
  261. check_type (dev, desc)
  262.      char *dev;
  263.      int desc;
  264. {
  265.   struct stat stats;
  266.  
  267.   if (_isrmt (desc))
  268.     return;
  269.   if (fstat (desc, &stats) == -1)
  270.     error (1, errno, "%s", dev);
  271.   if ((stats.st_mode & S_IFMT) != S_IFCHR)
  272.     error (1, 0, "%s is not a character special file", dev);
  273. }
  274.  
  275. void
  276. perform_operation (dev, desc, op, count)
  277.      char *dev;
  278.      int desc;
  279.      short op;
  280.      int count;
  281. {
  282.   struct mtop control;
  283.  
  284.   control.mt_op = op;
  285.   control.mt_count = count;
  286.   if (rmtioctl (desc, MTIOCTOP, &control))
  287.     error (2, errno, "%s", dev);
  288. }
  289.  
  290. void
  291. print_status (dev, desc)
  292.      char *dev;
  293.      int desc;
  294. {
  295.   struct mtget status;
  296.  
  297.   if (rmtioctl (desc, MTIOCGET, &status))
  298.     error (2, errno, "%s", dev);
  299.  
  300.   printf ("drive type = %d\n", (int) status.mt_type);
  301. #if defined(hpux) || defined(__hpux)
  302.   printf ("drive status (high) = %d\n", (int) status.mt_dsreg1);
  303.   printf ("drive status (low) = %d\n", (int) status.mt_dsreg2);
  304. #else
  305.   printf ("drive status = %d\n", (int) status.mt_dsreg);
  306. #endif
  307.   printf ("sense key error = %d\n", (int) status.mt_erreg);
  308.   printf ("residue count = %d\n", (int) status.mt_resid);
  309. #if !defined(ultrix) && !defined(__ultrix__) && !defined(hpux) && !defined(__hpux) && !defined(__osf__)
  310.   printf ("file number = %d\n", (int) status.mt_fileno);
  311.   printf ("block number = %d\n", (int) status.mt_blkno);
  312. #endif
  313. }
  314.  
  315. void
  316. usage (fp, status)
  317.   FILE *fp;
  318.   int status;
  319. {
  320.   fprintf (fp, "\
  321. Usage: %s [-V] [-f device] [--file=device] [--help] [--version] operation [count]\n",
  322.        program_name);
  323.   exit (status);
  324. }
  325.